use database::create_flow_run;
use instance::FlowInstance;
use shq_common::prelude::{get_my_pool, FlowState, RunProcess, StepDetail, StepState, SubmitType};

use crate::{
    config::get_workflow_config,
    executor::{cache::FlowCache, conf::get_managers, get_executor},
};
mod database;
mod instance;

/// 获取运行过程
pub async fn get_process(run_id: u64) -> anyhow::Result<RunProcess> {
    let mut fuc = FlowCache::from(run_id)?;
    let fi = fuc.get_flow_info().await?;
    let conf = get_workflow_config(fi.wfid, fi.version).ok_or(anyhow::anyhow!(
        "未找到wfid:{},version:{}流程配置",
        fi.wfid,
        fi.version
    ))?;
    let mut steps: Vec<StepDetail> = Vec::new();
    let flow_state: FlowState = fi.state.into();
    for s in conf.steps.iter() {
        let eis = get_executor(run_id, s.id,None).await?;
        let executors = eis.into_iter().map(|e| e.into()).collect();
        let state = if fi.step_id == s.id {
            if flow_state == FlowState::Completed {
                StepState::Done
            } else {
                StepState::Doing
            }
        } else if s.id < fi.step_id {
            StepState::Done
        } else {
            StepState::None
        };
        let step = StepDetail {
            id: s.id,
            name: s.name.clone(),
            executors,
            state,
        };
        steps.push(step);
    }
    let process = RunProcess {
        id: run_id,
        wfid: fi.wfid,
        name: conf.name.clone(),
        steps,
        state: flow_state,
        curr_step: fi.step_id,
    };
    Ok(process)
}

/// 创建流程
pub async fn create(wfid: u32, user_id: u32) -> anyhow::Result<u64> {
    create_flow_run(wfid, user_id).await
}
/// 提交
pub async fn submit(
    run_id: u64,
    user_id: u32,
    st: SubmitType,
    feed_back: Option<String>,
) -> anyhow::Result<()> {
    if user_id == 0 {
        return Err(anyhow::anyhow!("user_id不能为0"));
    }
    let mut tx = get_my_pool().begin().await?;
    let fi = FlowInstance::from(run_id).await?;
    let mas = get_managers(fi.wfid,fi.version).await?;
    let is_manager = mas.contains(&user_id);
    fi.submit(user_id, st, feed_back, is_manager,&mut tx).await?;
    tx.commit().await?;
    Ok(())
}

/// 批量提交
pub async fn submit_batch(
    run_ids: Vec<u64>,
    user_id: u32,
    st: SubmitType,
    feed_back: Option<String>,
    is_manager: bool,
) -> anyhow::Result<()> {
    if user_id == 0 {
        return Err(anyhow::anyhow!("user_id不能为0"));
    }
    let mut tx = get_my_pool().begin().await?;
    for run_id in run_ids {
        let fi = FlowInstance::from(run_id).await?;
        fi.submit(user_id, st, feed_back.clone(), is_manager,&mut tx).await?;
    }
    tx.commit().await?;
    Ok(())
}
